﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using Model.Hero;
using RemotingInterfaces;

namespace Model.Adventure
{
    //an encounter within the "dungeon". represents a room or area
    [Serializable]
    public class Encounter : IEncounter
    {
        private object thisLock = new object();
        //enviroment
        //inside, room is too dark to see properly (unlit room)
        private bool _env_inside, _env_dark;
        //enviromental factors cause periodic damage
        private Damage _periodic_damage;

        //private ManualResetEvent _MRE;

        private String _description, _name;

        private List<Character> _monsters;
        private List<Character> _heroes;
        private bool _cleared; //set to true when all monsters are dead
        private List<Encounter> _next_encounter; //what encounters are available when this encounter is cleared?
        //private Character _primary_target;
        //bosses can be represented with the hero class to increase complexity
        //private List<Hero.Hero> bosses; //doesnt necessarily needs to be a boss, but atleast more complex than an NPC
        //private Combat _combat; //combat module for computing combat

        /*REINFORCEMENTS*/
        //battle method should return after each round, check for live monster, and reinforcements are added as set by _reinforcements_arrival#
        //at which round do the reinforcements arrive?
        private int _reinforcements_arrival1, _reinforcements_arrival2, _reinforcements_arrival3;
        private List<Character> _reinforcements1, _reinforcements2, _reinforcements3;

        public Encounter()
        {
            _monsters = new List<Character>();            
            _name = "Encounter 1";
            _cleared = false;
            _next_encounter = new List<Encounter>();
        }

        public String Name
        {
            get { return _name; }
        }

        //when comming from the world builder, it is already a copy of a template monster
        public void AddMonster(Character monster)
        {
            //check monsters for feats giving them passive bonusses, ie. darkvision if _env_dark == true

            _monsters.Add(monster);
        }

        //start the encounter
        public void StartEncounter(List<Character> heroes, Combat combat) 
        {            
            _heroes = heroes;
            Console.WriteLine("StartEncounter()");            

            W: while (true)
            {
                //if (combat.Round > 3) return;
                //add reinforcements
                /*switch (combat.Round)
                {
                    case 0:
                        break;
                    case _reinforcements_arrival1:
                        break;
                    case _reinforcements_arrival2:
                        break;
                    case _reinforcements_arrival3:
                        break;
                }//*/

                foreach (Character _monster in _monsters)
                {
                    //alive monster found. continue combat and stop searching
                    if (_monster.CurrentHealth > 0)
                    {
                        //combat.Battle(_heroes, _monsters);
                        goto W;
                    }
                } //end foreach
                break;
            }//end repeat
            //RESET CD COUNTERS
            foreach (Hero.Hero hero in heroes) //heroes
            {
                if (hero.CurrentHealth > 0)
                    Console.WriteLine(hero.Name + " survived the fight with " + hero.CurrentHealth + " health left");
                long XP = 0;
                foreach (Character monster in _monsters)
                    XP += (monster as NPC).XP_Value;
                hero.AwardXP(XP / _monsters.Count);
                Console.WriteLine("{0} was awarded {1} XP", hero.Name, XP);
            }
        }//end startencounter
        /*
        public ManualResetEvent MRE
        {
            get { return _MRE; }
        }
        public Character PrimaryTarget
        {
            get { return _primary_target; }
            set
            {
                _primary_target = value;
                _combat.PrimaryTarget = value;                
            }
        }//*/

        /*public ICharacter GetRandomMonster()
        {
            return GetRandomMonster();
        }//*/

        public ICharacter GetRandomMonster()
        {
            //Console.WriteLine("Encounter::GetRandomMonster()");

            Character random_monster;

            var LiveMonsters = from monster in _monsters
                               where monster.CurrentHealth > 0
                               //orderby monster.Level
                               select monster;
         
            //not really random :D
            random_monster = LiveMonsters.Count() == 0 ? null : LiveMonsters.First();
            return random_monster;            
        }

        public override string ToString()
        {
            String str = "List of monsters in encounter:\n";
            foreach (Character monster in _monsters)
                str += monster.Name + "\n";
            return str + "\n";
        }
    }
}
